package XunChunCPU.EXE_SEC

import chisel3._
import XunChunCPU.Accelerator.WallaceTree16

class MulAccelerator extends Module{
    val io = IO(new Bundle{
        // ready信号
        val ready_in = Input(Bool())
        val ready_out = Output(Bool())
        // 16个部分积
        val P = Input(Vec(16,UInt(32.W)))
        val cs = Input(UInt(16.W))
    })
    // 32位,每位一个WallaceTree
    val wt0 = Module(new WallaceTree16)
    val wt1 = Module(new WallaceTree16)
    val wt2 = Module(new WallaceTree16)
    val wt3 = Module(new WallaceTree16)
    val wt4 = Module(new WallaceTree16)
    val wt5 = Module(new WallaceTree16)
    val wt6 = Module(new WallaceTree16)
    val wt7 = Module(new WallaceTree16)
    val wt8 = Module(new WallaceTree16)
    val wt9 = Module(new WallaceTree16)
    val wt10 = Module(new WallaceTree16)
    val wt11 = Module(new WallaceTree16)
    val wt12 = Module(new WallaceTree16)
    val wt13 = Module(new WallaceTree16)
    val wt14 = Module(new WallaceTree16)
    val wt15 = Module(new WallaceTree16)
    val wt16 = Module(new WallaceTree16)
    val wt17 = Module(new WallaceTree16)
    val wt18 = Module(new WallaceTree16)
    val wt19 = Module(new WallaceTree16)
    val wt20 = Module(new WallaceTree16)
    val wt21 = Module(new WallaceTree16)
    val wt22 = Module(new WallaceTree16)
    val wt23 = Module(new WallaceTree16)
    val wt24 = Module(new WallaceTree16)
    val wt25 = Module(new WallaceTree16)
    val wt26 = Module(new WallaceTree16)
    val wt27 = Module(new WallaceTree16)
    val wt28 = Module(new WallaceTree16)
    val wt29 = Module(new WallaceTree16)
    val wt30 = Module(new WallaceTree16)
    val wt31 = Module(new WallaceTree16)

    val Ns = Vec(32,Vec(16,Bool()))   //  每个WallaceTree的N输入
    for(i <- 0 until 32){
        for(j <- 0 until 16){
            Ns(i)(j) := io.P(j)(i)
        }
    }

    // WallaceTree的输入
    wt0.io.N := Ns(0)
    wt0.io.Cin := io.cs(14,0)      // cs(15)进入最终的A操作数的最后一位
    wt1.io.N := Ns(1)
    wt1.io.Cin := wt0.io.Cout
    wt2.io.N := Ns(2)
    wt2.io.Cin := wt1.io.Cout
    wt3.io.N := Ns(3)
    wt3.io.Cin := wt2.io.Cout
    wt4.io.N := Ns(4)
    wt4.io.Cin := wt3.io.Cout
    wt5.io.N := Ns(5)
    wt5.io.Cin := wt4.io.Cout
    wt6.io.N := Ns(6)
    wt6.io.Cin := wt5.io.Cout
    wt7.io.N := Ns(7)
    wt7.io.Cin := wt6.io.Cout
    wt8.io.N := Ns(8)
    wt8.io.Cin := wt7.io.Cout
    wt9.io.N := Ns(9)
    wt9.io.Cin := wt8.io.Cout
    wt10.io.N := Ns(10)
    wt10.io.Cin := wt9.io.Cout
    wt11.io.N := Ns(11)
    wt11.io.Cin := wt10.io.Cout
    wt12.io.N := Ns(12)
    wt12.io.Cin := wt11.io.Cout
    wt13.io.N := Ns(13)
    wt13.io.Cin := wt12.io.Cout
    wt14.io.N := Ns(14)
    wt14.io.Cin := wt13.io.Cout
    wt15.io.N := Ns(15)
    wt15.io.Cin := wt14.io.Cout
    wt16.io.N := Ns(16)
    wt16.io.Cin := wt15.io.Cout
    wt17.io.N := Ns(17)
    wt17.io.Cin := wt16.io.Cout
    wt18.io.N := Ns(18)
    wt18.io.Cin := wt17.io.Cout
    wt19.io.N := Ns(19)
    wt19.io.Cin := wt18.io.Cout
    wt20.io.N := Ns(20)
    wt20.io.Cin := wt19.io.Cout
    wt21.io.N := Ns(21)
    wt21.io.Cin := wt20.io.Cout
    wt22.io.N := Ns(22)
    wt22.io.Cin := wt21.io.Cout
    wt23.io.N := Ns(23)
    wt23.io.Cin := wt22.io.Cout
    wt24.io.N := Ns(24)
    wt24.io.Cin := wt23.io.Cout
    wt25.io.N := Ns(25)
    wt25.io.Cin := wt24.io.Cout
    wt26.io.N := Ns(26)
    wt26.io.Cin := wt25.io.Cout
    wt27.io.N := Ns(27)
    wt27.io.Cin := wt26.io.Cout
    wt28.io.N := Ns(28)
    wt28.io.Cin := wt27.io.Cout
    wt29.io.N := Ns(29)
    wt29.io.Cin := wt28.io.Cout
    wt30.io.N := Ns(30)
    wt30.io.Cin := wt29.io.Cout
    wt31.io.N := Ns(31)
    wt31.io.Cin := wt30.io.Cout 

    // 最终计算
    val A = Vec(32,Bool())
    val B = Vec(32,Bool())
    
    // A操作数
    A(0) := io.cs(15)
    A(1) := wt0.io.C
    A(2) := wt1.io.C
    A(3) := wt2.io.C
    A(4) := wt3.io.C
    A(5) := wt4.io.C
    A(6) := wt5.io.C
    A(7) := wt6.io.C
    A(8) := wt7.io.C
    A(9) := wt8.io.C
    A(10) := wt9.io.C
    A(11) := wt10.io.C
    A(12) := wt11.io.C
    A(13) := wt12.io.C
    A(14) := wt13.io.C
    A(15) := wt14.io.C
    A(16) := wt15.io.C
    A(17) := wt16.io.C
    A(18) := wt17.io.C
    A(19) := wt18.io.C
    A(20) := wt19.io.C
    A(21) := wt20.io.C
    A(22) := wt21.io.C
    A(23) := wt22.io.C
    A(24) := wt23.io.C
    A(25) := wt24.io.C
    A(26) := wt25.io.C
    A(27) := wt26.io.C
    A(28) := wt27.io.C
    A(29) := wt28.io.C
    A(30) := wt29.io.C
    A(31) := wt30.io.C
    // B操作数
    B(0) := wt0.io.S
    B(1) := wt1.io.S
    B(2) := wt2.io.S
    B(3) := wt3.io.S
    B(4) := wt4.io.S
    B(5) := wt5.io.S
    B(6) := wt6.io.S
    B(7) := wt7.io.S
    B(8) := wt8.io.S
    B(9) := wt9.io.S
    B(10) := wt10.io.S
    B(11) := wt11.io.S
    B(12) := wt12.io.S
    B(13) := wt13.io.S
    B(14) := wt14.io.S
    B(15) := wt15.io.S
    B(16) := wt16.io.S
    B(17) := wt17.io.S
    B(18) := wt18.io.S
    B(19) := wt19.io.S
    B(20) := wt20.io.S
    B(21) := wt21.io.S
    B(22) := wt22.io.S
    B(23) := wt23.io.S
    B(24) := wt24.io.S
    B(25) := wt25.io.S
    B(26) := wt26.io.S
    B(27) := wt27.io.S
    B(28) := wt28.io.S
    B(29) := wt29.io.S
    B(30) := wt30.io.S
    B(31) := wt31.io.S

    val mulAns = Wire(UInt(32.W))
    val trueA = Wire(UInt(32.W))
    val trueB = Wire(UInt(32.W))
    trueA := A
    trueB := B
    mulAns := trueA + trueB
}